using System.IO;

namespace SevenZSharp
{
   /// <summary>
   /// 
   /// </summary>
   public interface ICompressionDecoder : ICompressionMethod
   {
      /// <summary>
      /// Decodes a single file. <paramref name="inStream"/> is the
      /// encoded file which will be decoded into <paramref name="outStream"/>.
      /// If <paramref name="outStream"/> does not exist, it will be created.
      /// </summary>
      /// <param name="inStream">The in stream.</param>
      /// <param name="outStream">The out stream.</param>
      void DecodeSingleFile(FileStream inStream, FileStream outStream);

      /// <summary>
      /// Decodes a single file. <paramref name="inFile"/> is the
      /// path of the encoded file which will be decoded into <paramref name="outFile"/>.
      /// If <paramref name="outFile"/> does not exist, it will be created.
      /// </summary>
      /// <param name="inFile">The in file.</param>
      /// <param name="outFile">The out file.</param>
      void DecodeSingleFile(string inFile, string outFile);

      /// <summary>
      /// Recursively decodes the compressed file in <paramref name="inFile"/>
      /// into the output directory specified by <paramref name="outDirectory"/>.
      /// If <paramref name="outDirectory"/> does not exist, it will be created.
      /// 
      /// Supports: 7z (.7z), ZIP (.zip), GZIP (.gz), BZIP2 (.bz2) and TAR (.tar),
      /// RAR (.rar), CAB (.cab), ISO (.iso), ARJ (.arj), LZH (.lzh), CHM (.chm),
      /// Z (.Z), CPIO (.cpio), RPM (.rpm), DEB (.deb), NSIS (.nsis)
      /// </summary>
      /// <param name="inFile">The in file.</param>
      /// <param name="outDirectory">The out directory.</param>
      void DecodeIntoDirectory(string inFile, string outDirectory);
   }

   /// <summary>
   /// 
   /// </summary>
   public abstract class CompressionDecoder : ICompressionDecoder
   {
      #region ICompressionDecoder Members

      /// <summary>
      /// Decodes a single file. <paramref name="inStream"/> is the
      /// encoded file which will be decoded into <paramref name="outStream"/>.
      /// If <paramref name="outStream"/> does not exist, it will be created.
      /// </summary>
      /// <param name="inStream">The in stream.</param>
      /// <param name="outStream">The out stream.</param>
      public abstract void DecodeSingleFile(FileStream inStream, FileStream outStream);

      /// <summary>
      /// Decodes a single file. <paramref name="inFile"/> is the
      /// path of the encoded file which will be decoded into <paramref name="outFile"/>.
      /// If <paramref name="outFile"/> does not exist, it will be created.
      /// </summary>
      /// <param name="inFile">The in file.</param>
      /// <param name="outFile">The out file.</param>
      public virtual void DecodeSingleFile(string inFile, string outFile)
      {
         using (FileStream inStream = new FileStream(inFile, FileMode.Open, FileAccess.Read))
         {
            using (FileStream outStream = new FileStream(outFile, FileMode.OpenOrCreate, FileAccess.Write))
            {
               DecodeSingleFile(inStream, outStream);
            }
         }
      }

      /// <summary>
      /// Recursively decodes the compressed file in <paramref name="inFile"/>
      /// into the output directory specified by <paramref name="outDirectory"/>.
      /// If <paramref name="outDirectory"/> does not exist, it will be created.
      /// </summary>
      /// <param name="inFile">The in file.</param>
      /// <param name="outDirectory">The out directory.</param>
      public abstract void DecodeIntoDirectory(string inFile, string outDirectory);

      #endregion
   }
}